package com.xique.park.service.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xique.common.core.utils.DateUtils;
import com.xique.common.core.utils.StringUtils;
import com.xique.common.datascope.annotation.NeedSetDictLabel;
import com.xique.common.datascope.annotation.NeedSetFieldValue;
import com.xique.park.bean.domain.ParkIn;
import com.xique.park.bean.domain.ParkInV1;
import com.xique.park.bean.dto.ParkInDto;
import com.xique.park.controller.client.web.bean.dto.ParkInOut;
import com.xique.park.controller.client.web.bean.search.ParkInSearch;
import com.xique.park.mapper.ParkInMapper;
import com.xique.park.mapper.ParkInMapperV1;
import com.xique.park.service.service.IParkInService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * 入场记录Service业务层处理
 *
 * @author xique
 * @date 2021-12-09
 */
@Slf4j
@Service
public class ParkInServiceImpl extends ServiceImpl<ParkInMapper, ParkIn> implements IParkInService {

    @Autowired
    private ParkInMapper parkInMapper;

    @Autowired
    private ParkInMapperV1 parkInMapperV1;

    @Autowired
    private SqlSessionFactory sqlSessionFactory;

    /**
     * 查询入场记录
     *
     * @param id 入场记录ID
     * @return 入场记录
     */
    @Override
    @NeedSetFieldValue
    @NeedSetDictLabel
    public ParkIn selectParkInById(Long id) {
        return parkInMapper.selectParkInById(id);
    }

    @Override
    public List<ParkIn> selectParkInByIds(List<Long> parkInIdList) {
        return parkInMapper.selectParkInByIds(parkInIdList);
    }

    /**
     * 查询入场记录列表
     *
     * @param parkIn 入场记录
     * @return 入场记录
     */
    @Override
    public List<ParkIn> selectParkInList(ParkIn parkIn) {
        return parkInMapper.selectParkInList(parkIn);
    }

    /**
     * 新增入场记录
     *
     * @param parkIn 入场记录
     * @return 结果
     */
    @Override
    public int insertParkIn(ParkIn parkIn) {
        parkIn.setCreateTime(DateUtils.getNowDate());
        return parkInMapper.insertParkIn(parkIn);
    }

    /**
     * 修改入场记录
     *
     * @param parkIn 入场记录
     * @return 结果
     */
    @Override
    public int updateParkIn(ParkIn parkIn) {
        parkIn.setUpdateTime(DateUtils.getNowDate());
        return parkInMapper.updateParkIn(parkIn);
    }

    /**
     * 批量删除入场记录
     *
     * @param ids 需要删除的入场记录ID
     * @return 结果
     */
    @Override
    public int deleteParkInByIds(Long[] ids) {
        return parkInMapper.deleteParkInByIds(ids);
    }

    @Override
    public Integer selectParkInfoNumByToday(Integer province, Integer city, Integer district, Long deptId, Long parkInfoId) {
        return parkInMapper.selectParkInfoNumByToday(province, city, district, deptId, parkInfoId);
    }

    @Override
    public List<ParkInDto> selectParkInRealTimeStatus(Integer limit, Integer province, Integer city, Integer district, Long deptId, Long parkInfoId) {
        return parkInMapper.selectParkInRealTimeStatus(limit, province, city, district, deptId, parkInfoId);
    }

    @Override
    public List<ParkInDto> selectTrafficFlowByDateAndTime(String day, Integer startHour, Integer endHour, Integer province, Integer city, Integer district, Long deptId, Long parkInfoId) {
        ParkInDto parkInDto;
        List<ParkInDto> parkInDtoList = new ArrayList<>();
        for (int time = startHour; time <= endHour; time++) {
            if (time < 0) {
                int newTime = time + 24;
                String newDay = DateUtils.getPastDate(DateUtils.parseDate(day), 1);
                String startDayTime = newDay + " " + newTime + ":00:00";
                String endDayTime = newDay + " " + newTime + ":59:59";
                parkInDto = parkInMapper.selectTrafficFlowByDateAndTime(startDayTime, endDayTime, province, city, district, deptId, parkInfoId);
                parkInDto.setHourTime(newTime);
            } else {
                String startDayTime = day + " " + time + ":00:00";
                String endDayTime = day + " " + time + ":59:59";
                parkInDto = parkInMapper.selectTrafficFlowByDateAndTime(startDayTime, endDayTime, province, city, district, deptId, parkInfoId);
                parkInDto.setHourTime(time);
            }
            parkInDtoList.add(parkInDto);
        }
        return parkInDtoList;
    }

    @Override
    public List<ParkInDto> selectParkInByParkingSerial(Long parkId, String parkingSerial) {
        return parkInMapper.selectParkInByParkingSerial(parkId, parkingSerial);
    }

    @Override
    public ParkInV1 selectParkIn(ParkInSearch search) {
        QueryWrapper<ParkInV1> wrapper = new QueryWrapper<>();
        if (null != search.getId()) {
            wrapper.eq("id", search.getId());
        }
        if (null != search.getLaneIds()) {
            wrapper.in("in_lane_id", search.getLaneIds());
        }
        if (null != search.getLaneId()) {
            wrapper.eq("in_lane_id", search.getLaneId());
        }
        if (StringUtils.isNotEmpty(search.getParkingSerial())) {
            wrapper.eq("parking_serial", search.getParkingSerial());
        }
        wrapper.orderByDesc("UNIX_TIMESTAMP(update_time)").last("limit 1");

        return parkInMapperV1.selectOne(wrapper);
    }

    @Override
    public List<ParkIn> selectLastParkInListByLaneId(Long parkId, List<Long> laneIds) {
        if (CollectionUtils.isEmpty(laneIds)) {
            return new ArrayList<>();
        }
        return parkInMapper.selectLastParkInListByLaneId(parkId, laneIds);
    }

    @Override
    @NeedSetFieldValue
    @NeedSetDictLabel
    public List<ParkInOut> selectParkInOutList(ParkIn parkIn) {
        return parkInMapper.selectParkInOutList(parkIn);
    }

    @Override
    public List<ParkInDto> selectParkInByPlate(Long parkId, String plate) {
        return parkInMapper.selectParkInByPlate(parkId, plate);
    }

    /**
     * 车辆进场
     */
    @Override
    public long getInCarRevenue(Long parkId, Date starDate, Date endDate) {
        return parkInMapper.getInCarRevenue(parkId, starDate, endDate);
    }

    @Override
    public List<ParkInDto> statisticsByMngTypeAndDay(Long parkId, List<String> mngTypeList) {
        return parkInMapper.statisticsByMngTypeAndDay(parkId, mngTypeList);
    }

    @Override
    public long statisticsByMngTypeAndAppointDay(Long parkId, String day, List<String> mngTypeList) {
        return parkInMapper.statisticsByMngTypeAndAppointDay(parkId, day, mngTypeList);
    }

    @Override
    public List<ParkIn> selectParkIn(ParkIn parkIn) {
        return parkInMapper.selectParkIn(parkIn);
    }

    @Override
    public List<ParkIn> selectParkInIdByInLaneId(Long parkId, List<Long> laneIdList, int limit) {
        return parkInMapper.selectParkInIdByInLaneId(parkId, laneIdList, limit);
    }

    @Override
    public void batchDel(Set<Long> inIdSet) {
        long startTime = System.currentTimeMillis();
        SqlSession sqlSession = null;
        try {
            sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
            ParkInMapper parkInMapper = sqlSession.getMapper(ParkInMapper.class);
            inIdSet.forEach(parkInMapper::deleteParkInById);
            sqlSession.commit();
            sqlSession.clearCache();
        } catch (Exception e) {
            log.info("[入场记录服务]-批量删除异常，异常信息：{}", e.getMessage());
            e.printStackTrace();
            if (sqlSession != null) {
                sqlSession.rollback();
            }
        } finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }
        log.info("[入场记录服务]-批量删除耗时：{}毫秒", System.currentTimeMillis() - startTime);
    }

}
